﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Migrator.Packets;
using Migrator.Entities;
using Migrator.Util;

namespace Migrator.Services.Registration.Packets
{
    /// <summary>
    /// MobileIP Registration request packet
    /// 
    /// Packet structure:
    /// 
    /// 0                   1                   2                   3
    /// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    /// |     Type      |S|B|D|M|G|r|T|x|          Lifetime             |
    /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    /// |                          Home Address                         |
    /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    /// |                           Home Agent                          |
    /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    /// |                        Care-of Address                        |
    /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    /// |                                                               |
    /// +                         Identification                        +
    /// |                                                               |
    /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    /// | Extensions ...
    /// +-+-+-+-+-+-+-+-
    /// </summary>
    public class RegistrationRequestPacket : UDPPacket
    {
        public RegistrationRequestPacket(Node source, IPAddress destinationIP)
            : base(source, destinationIP, 433, 434)
        {
            this.SourceIP = source.IPAddress;
            this.HomeAddress = source.IPAddress;
        }

        /// <summary>
        /// When using a co-located care-of address, the source ip is not the home
        /// address, but the co-located address.
        /// </summary>
        /// <param name="source">The node who sends the request.</param>
        /// <param name="sourceIP">The node's co-located care-of address</param>
        /// <param name="destinationIP">Packet destination</param>
        public RegistrationRequestPacket(Node source, IPAddress sourceIP, IPAddress destinationIP)
            : base(source, destinationIP, 433, 434)
        {
            this.SourceIP = sourceIP;
            this.HomeAddress = source.IPAddress;
        }

        #region Packet fields

        public override IPAddress SourceIP
        {
            get;
            protected set;
        }

        public int Type
        {
            get { return 1; }
        }

        /// <summary>
        /// Simultaneous bindings
        /// </summary>
        public bool S
        {
            get;
            set;
        }

        /// <summary>
        /// Broadcast datagrams.
        /// </summary>
        public bool B
        {
            get;
            set;
        }

        /// <summary>
        /// Decapsulation by mobile node.
        /// </summary>
        public bool D
        {
            get;
            set;
        }

        /// <summary>
        /// Minimal encapsulation.
        /// </summary>
        public bool M
        {
            get;
            set;
        }

        /// <summary>
        /// GRE encapsulation.
        /// </summary>
        public bool G
        {
            get;
            set;
        }

        /// <summary>
        /// Reverse Tunneling requested
        /// </summary>
        public bool T
        {
            get;
            set;
        }

        /// <summary>
        /// The number of seconds remaining before the registration
        /// is considered expired.
        /// </summary>
        public ushort Lifetime
        {
            get;
            set;
        }

        /// <summary>
        /// The IP address of the mobile node.
        /// </summary>
        public IPAddress HomeAddress
        {
            get;
            set;
        }

        /// <summary>
        /// The IP address of the mobile node's home agent.
        /// </summary>
        public IPAddress HomeAgent
        {
            get;
            set;
        }

        /// <summary>
        /// The IP address for the end of the tunnel.
        /// </summary>
        public IPAddress CareOfAddress
        {
            get;
            set;
        }

        #endregion
    }
}
